import { Message } from './msg1'

const sceneMap = {
  p2p: 0,
  team: 1,
  superTeam: 5
}
const clientTypeMap = {
  Android: 1,
  iOS: 2,
  PC: 4,
  WindowsPhone: 8,
  Web: 16,
  Server: 32,
  Mac: 64,
  HarmonyOS: 65
}
const typeMap = {
  text: 0,
  image: 1,
  audio: 2,
  video: 3,
  geo: 4,
  notification: 5,
  file: 6,
  tip: 10,
  robot: 11,
  g2: 12,
  custom: 100
}

const notificationTypeReverseMap = {
  addTeamMembers: 0,
  removeTeamMembers: 1,
  leaveTeam: 2,
  updateTeam: 3,
  dismissTeam: 4,
  passTeamApply: 5,
  transferTeam: 6,
  addTeamManagers: 7,
  removeTeamManagers: 8,
  acceptTeamInvite: 9,
  updateTeamMute: 10,
  netcallMiss: 101,
  netcallBill: 102,
  netcallReject: 103,
  addSuperTeamMembers: 401,
  removeSuperTeamMembers: 402,
  leaveSuperTeam: 403,
  updateSuperTeam: 404,
  dismissSuperTeam: 405,
  transferSuperTeam: 406,
  addSuperTeamManagers: 407,
  removeSuperTeamManagers: 408,
  updateSuperTeamMembersMute: 409,
  passSuperTeamApply: 410,
  acceptSuperTeamInvite: 411
}

function booleanToInt(data: boolean): number {
  return data ? 1 : 0
}

const msgTag = {
  scene: {
    id: 0,
    converter(data: any): any {
      return sceneMap[data as keyof typeof sceneMap]
    }
  },
  to: 1,
  from: 2,
  fromClientType: {
    id: 4,
    converter(data: any): any {
      return clientTypeMap[data as keyof typeof clientTypeMap]
    }
  },
  fromDeviceId: 5,
  fromNick: 6,
  time: 7,
  type: {
    id: 8,
    converter(data: any): any {
      return typeMap[data as keyof typeof typeMap]
    }
  },
  body: {
    id: 9,
    converter(data: any, message: any): any {
      switch (message.type) {
        case 'text':
          return message.text
        case 'image':
        case 'audio':
        case 'video':
        case 'file':
          return undefined
        case 'geo':
          return undefined
        case 'notification':
          // todo 进一步解析
          return undefined
        case 'custom':
          return undefined
        case 'tip':
          return message.tip
        default:
          return undefined
      }
    }
  },
  attach: {
    id: 10,
    converter(data: any, message: any): any {
      switch (message.type) {
        case 'text':
          return undefined
        case 'image':
        case 'audio':
        case 'video':
        case 'file':
          try {
            return JSON.stringify(message.file)
          } catch (err) {
            return undefined
          }
        case 'geo':
          try {
            return JSON.stringify(message.geo)
          } catch (err) {
            return undefined
          }
        case 'notification':
          // todo 进一步解析
          return {
            id: notificationTypeReverseMap[message.attach.type as keyof typeof notificationTypeReverseMap]
          }
        case 'custom':
          return message.content
        case 'tip':
          return message.attach
        default:
          return undefined
      }
    }
  },
  idClient: 11,
  idServer: 12,
  resend: {
    id: 13,
    converter: booleanToInt
  },
  userUpdateTime: 14,
  custom: {
    id: 15,
    converter(data: any): any {
      if (typeof data === 'object') {
        return JSON.stringify(data)
      } else {
        return data
      }
    }
  },
  clientAntiSpam: {
    id: 24,
    converter: booleanToInt
  },
  needMsgReceipt: {
    id: 26,
    converter: booleanToInt
  },
  replyMsgFromAccount: 29,
  replyMsgToAccount: 30,
  replyMsgTime: 31,
  replyMsgIdServer: 32,
  replyMsgIdClient: 33,
  threadMsgFromAccount: 34,
  threadMsgToAccount: 35,
  threadMsgTime: 36,
  threadMsgIdServer: 37,
  threadMsgIdClient: 38,
  callbackExt: 40,
  subType: 41,
  env: 43,
  yidunAntiSpamRes: 45,
  isHistoryable: {
    id: 100,
    converter: booleanToInt
  },
  isRoamingable: {
    id: 101,
    converter: booleanToInt
  },
  isSyncable: {
    id: 102,
    converter: booleanToInt
  },
  isMuted: {
    id: 104,
    converter: booleanToInt
  },
  cc: {
    id: 105,
    converter: booleanToInt
  },
  isInBlackList: {
    id: 106,
    converter: booleanToInt
  },
  isPushable: {
    id: 107,
    converter: booleanToInt
  },
  isOfflinable: {
    id: 108,
    converter: booleanToInt
  },
  isUnreadable: {
    id: 109,
    converter: booleanToInt
  },
  needPushNick: {
    id: 110,
    converter: booleanToInt
  },
  isReplyMsg: {
    id: 111,
    converter: booleanToInt
  },
  tempTeamMemberCount: 112
}

const msgKeys = Object.keys(msgTag)

export function parseMsg(data: Message): any {
  return msgKeys.reduce((acc, key) => {
    const strat = msgTag[key as keyof typeof msgTag]
    const value = data[key as keyof typeof data]
    if (typeof strat === 'number') {
      if (typeof value !== 'undefined') {
        acc[strat] = value.toString()
      }
    } else {
      const id = strat.id
      const converter = strat.converter
      const result = converter(value, data)
      if (typeof result !== 'undefined') {
        acc[id] = result.toString()
      }
    }
    return acc
  }, {} as any)
}
